#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "log.hpp"
#include "ThreadPoll.hpp"
#include "Daemon.hpp"

const uint16_t defaultport = 8888;
const std::string defaultip = "0.0.0.0";

enum 
{
    SOCKET_ERR,
    BIND_ERR ,
    LISTEN_ERR
};



class Tcpserver
{
    static void* Service(void* cd)
    {
        pthread_detach(pthread_self());

        Client_Data* cd_ = (Client_Data*)cd;
        int fd = cd_->c_sockfd_;
        char buffer[1024];
        while(true)
        {
            int n = read(fd , buffer , sizeof(buffer));
            if(n > 0)
            {
                buffer[n] = 0;
                std::cout << "get a message : " << buffer << std::endl;
            }
            //发送回去
            write(fd , buffer , sizeof(buffer));
        }
        delete cd_;
        return nullptr;
    }

public:
    // 初始化
    Tcpserver(const uint16_t port = defaultport , std::string ip = defaultip)
    :port_(port)  , ip_(ip) , isrunning(false)
    {}

    // 进行初始化
    void Init()
    {
        // 分为三步 : 创建套接字  ,  绑定  , 设置监听
         
        // 1. 创建套接字
        sockfd_ = socket(AF_INET , SOCK_STREAM , 0);
        if(sockfd_ < 0)
        {
            lg_(Fatal , "socket failed , errno message : %s , errno : %d ", strerror(errno) , errno);
            exit(SOCKET_ERR);
        }

        // 2. 绑定
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = htons(port_);
        inet_aton(ip_.c_str() , &(server.sin_addr));
        unsigned int len = sizeof(server);
        if(bind(sockfd_ , (sockaddr*)&server , len) < 0)
        {
            lg_(Fatal , "bind failed , errno message : %s , errno : %d ", strerror(errno) , errno);
            exit(BIND_ERR);
        }

        // 3.设置监听模式
        if(listen(sockfd_ , 10) < 0) 
        {
            lg_(Fatal , "listen failed , errno message : %s , errno : %d ", strerror(errno) , errno);
            exit(LISTEN_ERR);
        }
    }


    // 运行
    void Running()
    {
        isrunning = true;
        //Daemon d;
        lg_(Info , "server run sucess");
        ThreadPoll* tp = ThreadPoll::GetThreadPoll();
        tp->Start();
        while(isrunning)
        {
            // 1. accept接受客户端的请求
            struct sockaddr_in client;
            unsigned int len = sizeof(client);
            int sockfd = accept(sockfd_ , (sockaddr*)&client, &len);
            if(sockfd < 0)
            {
                lg_(Warning , "accept failed , errno message : %s , errno : %d ", strerror(errno) , errno);
                continue;
            }
            
            // 2. 获取用户的IP和端口信息
            uint16_t clientport = client.sin_port;
            std::string clientip = inet_ntoa(client.sin_addr);
            Client_Data* cd = new Client_Data(clientport, clientip , sockfd);
            lg_(Info , "accept a client : [%s : %d]" , clientip.c_str() , clientport);
 
            // 3. 向线程池中发送任务
            Task tk(cd);
            tp->Push(cd);
        }
    }   


private:
    int sockfd_;
    uint16_t port_;
    std::string ip_;
    bool isrunning;
};